#include "Core.h"
#include "QueryManager.h"
#include "Protocol/ProtocolHelper.h"
#include "Command/Transaction/GetVersion.h"

using namespace Common;
using namespace Transport;
using namespace Log;

Core::Core(QObject* parent) :
	QObject(parent),
	_queryManager(new QueryManager(*this, this)),
	_logManager(NULL)
{
}

void Core::openConnection(QString ip, int port)
{
	ClientThread *client = new ClientThread();
	client->setServer(ip, port);
	connect(client, SIGNAL(finished()), client, SLOT(deleteLater()));
	connect(client, SIGNAL(receivedMessage(QByteArray)), this, SLOT(onMessageRecieved(QByteArray)));
	connect(client, SIGNAL(connectionError(QString)), this, SLOT(onConnectionError(QString)));
	connect(client, SIGNAL(wasConnected()), this, SLOT(onConnected()));
	connect(client, SIGNAL(wasDisconnected()), this, SLOT(onDisconnected()));

	_transport = client;

	client->start();
}

void Core::closeConnection()
{
	if(!_transport) return;
	_transport->closeConnection();
	//_transport->deleteLater();
}

void Core::addCommand(ICommand::SPtr command)
{
	_queryManager->addCommand(command);
}

void Core::onMessageRecieved(QByteArray data)
{
	processMessage(data);
}

void Core::addLogMsg(QString msg, ILogManager::LogType type)
{
	qDebug() << msg;
	if(_logManager) _logManager->addLogMessage(msg, type);
}

void Core::onConnected()
{
	addLogMsg("Successfuly connected");
	emit connected();

	//_queryManager->addCommand(ICommand::SPtr(new Command::GetVersion()));
}

void Core::onDisconnected()
{
	addLogMsg("Successfuly disconnected");
	emit disconnected();
}

void Core::onConnectionError(QString err)
{
	QString msg = QString("Connection error :: %1").arg(err);
	addLogMsg(msg, ILogManager::WARN);
}

void Core::processMessage(QByteArray data)
{
	qDebug() << "Input[" << data.size() << "]: " << data.toHex();

	if(data.isEmpty())
		return;

	QDataStream readStream(&data, QIODevice::ReadOnly);

	quint8 messageType;

	readStream >> messageType;

		QByteArray recievedBa = data;
		recievedBa.remove(0, 1);
		QString msg = "<< " + Protocol::Helper::commandToHexString(data);
		addLogMsg(msg);

	switch(messageType)
	{
	case TEXT_INDICATION:
		//_queryManager->addCommand(ICommand::SPtr(new Command::LogItem(data)));
		break;
	default:
		_queryManager->processResponse(data);
		break;
	}
}
